package cn.zswltech.gruul.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
    private final static Logger logger = LoggerFactory.getLogger(StringUtil.class);
    /**
     * 正则表达式：验证邮箱
     */
    private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

    public static final String EMPTY = "";

    private static final Pattern numericPattern = Pattern.compile("[0-9]*");

    private static final Pattern phonePattern = Pattern.compile("^1\\d{10}$");

    public static boolean isEmpty(String s) {
        if (s == null || s.length() == 0) {
            return true;
        }
        return false;
    }

    public static boolean isNotEmpty(String s) {
        return !isEmpty(s);
    }

    public static boolean isBlank(String s) {
        int strLen;
        if (s == null || (strLen = s.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(s.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    public static boolean isNotBlank(String s) {
        return !isBlank(s);
    }

    public static String trimToEmpty(String input) {
        if (input == null) {
            return EMPTY;
        }
        return input.trim();
    }

    public static String trimToSize(String input, int size) {
        if (input == null) {
            return EMPTY;
        }
        if (input.length() < size) {
            return input;
        }
        return input.substring(0, size);
    }

    /**
     * @param str
     * @return
     */
    public static String uppercaseFirstLetter(String str) {
        if (isEmpty(str)) {
            return str;
        }
        char firstLetter = str.charAt(0);
        firstLetter = Character.toUpperCase(firstLetter);
        return firstLetter + str.substring(1);
    }

    /**
     * @param str
     * @return
     */
    public static String lowercaseFirstLetter(String str) {
        if (isEmpty(str)) {
            return str;
        }
        char firstLetter = str.charAt(0);
        firstLetter = Character.toLowerCase(firstLetter);
        return firstLetter + str.substring(1);
    }

    public static String replace(String inString, String oldPattern, String newPattern) {
        if (isEmpty(inString) || isEmpty(oldPattern) || newPattern == null) {
            return inString;
        }
        StringBuilder sbuf = new StringBuilder();
        int pos = 0;
        int index = inString.indexOf(oldPattern);
        int patLen = oldPattern.length();
        while (index >= 0) {
            sbuf.append(inString.substring(pos, index));
            sbuf.append(newPattern);
            pos = index + patLen;
            index = inString.indexOf(oldPattern, pos);
        }
        sbuf.append(inString.substring(pos));
        return sbuf.toString();
    }

    public static String camelToFixedString(String str, String fixed) {
        str = trimToEmpty(str);
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); ++i) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                if (i != 0) {
                    sb.append(fixed);
                }
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    private static String fixedCharToCamel(String str, Set<Character> fixedChars) {
        str = trimToEmpty(str);
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        final int len = str.length();
        for (int i = 0; i < len; ++i) {
            char c = str.charAt(i);
            if (fixedChars.contains(c)) {
                ++i;
                if (i != len) {
                    c = Character.toUpperCase(str.charAt(i));
                    sb.append(c);
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * @param input
     * @param token
     * @return
     */
    public static String getFirstBefore(String input, String token) {
        if (isEmpty(input)) {
            return input;
        }
        int pos = input.indexOf(token);
        if (pos < 0) {
            return input;
        }
        return input.substring(0, pos);
    }

    public static String getFirstAfter(String input, String token) {
        if (isEmpty(input)) {
            return input;
        }
        int pos = input.indexOf(token);
        if (pos < 0) {
            return input;
        }
        return input.substring(pos + token.length());
    }

    /**
     * @param input
     * @param input
     * @param token
     * @return
     */
    public static String getLastBefore(String input, String token) {
        if (isEmpty(input)) {
            return input;
        }
        int pos = input.lastIndexOf(token);
        if (pos < 0) {
            return input;
        }
        return input.substring(0, pos);
    }

    public static String getLastAfter(String input, String token) {
        if (isEmpty(input)) {
            return input;
        }
        int pos = input.lastIndexOf(token);
        if (pos < 0) {
            return input;
        }
        return input.substring(pos + token.length());
    }


    public static boolean equals(String s1, String s2) {
        if (s1 == s2) {
            return true;
        }
        if (s1 == null || s2 == null) {
            return false;
        }
        return s1.equals(s2);
    }

    public static int getWordCount(String s) {
        s = s.replaceAll("[^\\x00-\\xff]", "**");
        int length = s.length();
        return length;
    }

    public static String getNewWord(String str, int length) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (isChinese(str.charAt(i))) {
                count += 2;
            } else {
                count++;
            }
            if (count > length) {
                return str.substring(0, i);
            }
        }
        return str;
    }

    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
            return true;
        }
        return false;
    }

    public static String hideString(String str, int start, int length) {
        if (isEmpty(str)) {
            return "";
        }
        int l = str.length();
        if (start < 0) {
            start = 0;
        }
        if (start > l) {
            start = l;
        }
        if (length < 0) {
            length = 0;
        }
        if (length > l - start) {
            length = l - start;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append("*");
        }
        str = str.substring(0, start) + sb.toString() + str.substring(start + length);
        return str;
    }


    public static boolean isPhone(String mobileNum) {
        if (isEmpty(mobileNum)) {
            return false;
        }

        Matcher m = phonePattern.matcher(mobileNum);
        return m.matches();
    }

    public static String limit(String context, int length) {
        if (isEmpty(context)) {
            return "";
        }
        if (length == 0) {
            return "";
        }
        if (context.length() < length) {
            return context;
        } else {
            return context.substring(0, length - 1) + "...";
        }
    }

    public static String wholeUrl(String url) {
        if (isEmpty(url)) {
            return "";
        }
        if (url.indexOf("http://") > -1 || url.indexOf("https://") > -1) {
            return url;
        }
        return "http://" + url;
    }

    public static boolean hasStr(String str, String content) {
        if (isEmpty(str)) {
            return false;
        }
        return str.indexOf(content) > -1;
    }

    public static String toString(Object obj) {
        if (obj == null) {
            return "";
        }
        return obj.toString();
    }

    public static boolean isNumeric(String str) {
        if (isEmpty(str)) {
            return false;
        }
        return numericPattern.matcher(str).matches();
    }

    public static boolean isUrl(String url) {
        if (isEmpty(url)) {
            return false;
        }
        if (url.indexOf("http://") > -1 || url.indexOf("https://") > -1) {
            return true;
        }
        return false;
    }

    /**
     * 隐藏多余的字符
     *
     * @param context
     * @param length
     * @return
     */
    public static String substringByLength(String context, int length) {
        if (context.length() < length) {
            return context;
        } else {
            return context.substring(0, length - 1) + "...";
        }
    }

    /**
     * 字符转码
     */
    public static String transCode(String str, String sourceCode, String targetCode) throws UnsupportedEncodingException {
        if (isEmpty(str)) {
            return "";
        }
        str = new String(str.getBytes(sourceCode), targetCode);
        return str;
    }

    /**
     * 字符串转Integer
     *
     * @param str
     * @return
     */
    public static Integer str2Integer(String str) {
        if (isBlank(str)) {
            return null;
        } else {
            try {
                return Integer.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
    }

    /**
     * 字符串转int
     *
     * @param str
     * @return
     */
    public static int str2Int(String str) {
        if (isBlank(str)) {
            return 0;
        } else {
            try {
                return Integer.parseInt(str);
            } catch (Exception e) {
                return 0;
            }

        }
    }

    public static Long str2Long(String str) {
        if (isBlank(str)) {
            return null;
        } else {
            try {
                return Long.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
    }

    public static String object2Str(Object str) {
        if (str == null) {
            return null;
        } else {
            return str.toString();
        }
    }

    public static Date timeMillisStr2Date(String timeMillis) {
        return timeMillis2Date(str2Long(timeMillis));
    }

    public static Date timeMillis2Date(Long timeMillis) {
        if (timeMillis == null) {
            return null;
        }
        Date date = new Date();
        date.setTime(timeMillis);
        return date;
    }

    /**
     * 对象转Integer
     *
     * @param str
     * @return
     */
    public static Integer obj2Integer(Object str) {
        if (str == null || StringUtils.isBlank(str.toString())) {
            return null;
        }
        try {
            return Integer.valueOf(str.toString());
        } catch (Exception e) {
            return null;
        }

    }


    /**
     * 校验邮箱
     *
     * @param email
     * @return 校验通过返回true，否则返回false
     */
    public static boolean isEmail(String email) {
        return Pattern.matches(REGEX_EMAIL, email);
    }

    /**
     * 解析JSONObject
     *
     * @param string
     * @return
     */
    public static JSONObject parseJSONObject(String string) {
        try {
            return JSON.parseObject(string);
        } catch (Exception e) {
            logger.error("Parse JSON object error, param:{}", e, string);
        }
        return null;
    }

    /**
     * 解析JSONArray
     *
     * @param string
     * @return
     */
    public static JSONArray parseJSONArray(String string) {
        try {
            return JSON.parseArray(string);
        } catch (Exception e) {
            logger.error("Parse JSON array error, param:{}", e, string);
        }
        return null;
    }
}
